package ajakuulauku;

import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;

public class Game extends Engine implements MouseInputListener {

	private BufferedImage backgroundImg = GUI.loadBufferedImage("images/Background-1.png");
	/**
	 * Constructor for Game, initializes Canvas and adds MouseListener
	 * @throws InvocationTargetException 
	 * @throws InterruptedException 
	 */
	public Game () {
		
		Runnable doWorkRunnable = new Runnable() {
		    public void run() { 
		    	canv.init();
		    }
		};
		try {
			SwingUtilities.invokeAndWait(doWorkRunnable);
		}catch(Exception e) {}
		canv.addMouseListener(this);
	}
	
	/**
	 * Update, runs every cycle, that is every 15 ms.
	 * Calls draw, update methods
	 */
	@Override
	void update() {
		canv.graphics.drawImage(backgroundImg, null, 0, 0);
		
		CollisionHandler handler = new CollisionHandler();
		for (GameObject go : CurrentLevel.allObjects) {
			go.Update();
		}
		
		// ball collision
		while (handler.frameTime < 1) {	
			handler.checkCollisions();
		}

		// update ball and draw stuff
	
		/*CurrentLevel.hole.draw(canv.graphics);
		CurrentLevel.ball.Update();
		CurrentLevel.ball.draw(canv.graphics);*/
		for (GameObject go : CurrentLevel.allObjects) {
			go.draw(canv.graphics);
		}
		canv.display();
		
		if (CurrentLevel.objectCollections.get("hole") != null) {
			// handle player loss
			if (checkEnd())
			   finishGame("You lost :(");
			
			// handle player win
			if (checkWin())
			   finishGame("Good job! You grabbed victory.");
		}
	}
	
	
	/**
	 * Ends the current level with a popup.
	 * @param message The message to display in popup.
	 */
	private void finishGame(String message) {
	   JOptionPane.showMessageDialog(canv, message);
	   cleanUp();
	}
	
	/**
	 * Checks if player has won.
	 * @return True, if player has completed the level.
	 */
	private boolean checkWin() {
		Ball ball;
		ArrayList<GameObject> balls = CurrentLevel.objectCollections.get("ball");
		Hole hole;
		ArrayList<GameObject> holes = CurrentLevel.objectCollections.get("hole");
		
		for (int i = 0; i < balls.size(); i++) {
			ball = (Ball)balls.get(i);
			for (int j = 0; j < holes.size(); j++) {
				hole = (Hole)holes.get(i);
				
				double distance = new Vector2(ball.getX() - hole.getX(), ball.getY() - hole.getY()).length();
				if (distance < ((ball.getRadius() + hole.getRadius()) / 2))
					return true;
			}
		}
		return false;
	}
	
	/**
	 * Checks if player has lost the level.
	 * @return True, if player has lost.
	 */
	private boolean checkEnd() {	 
		Ball ball;
		ArrayList<GameObject> balls = CurrentLevel.objectCollections.get("ball");
		
		for (int i = 0; i < balls.size(); i++) {
			ball = (Ball)balls.get(i);
			// check if out of bounds
			double currentX = ball.getX();
			double currentY = ball.getY();
			double r = ball.getRadius();
			if (currentX < (0 - r) || currentX > (GUI.WIDTH + r) || currentY < (0 - r) || currentY > (GUI.HEIGHT + r))
				return true;
		   
			// check if ball not moving with all magnets turned off
			boolean ballMoving = true;
			boolean allMagnetsActivated = false;
			if (!ball.isMoving()) {
				ballMoving = false;
			}
			if ((CurrentLevel.objectCollections.get("magnet").size() != 0) && (CurrentLevel.objectCollections.get("magnet").size() == CurrentLevel.activated.size()))
				allMagnetsActivated = true;
			if (!ballMoving && allMagnetsActivated)
				return true;
		   
			}
		return false;
	}

	/**
	 * Turns on the magnet, if player clicked on it.
	 */
	@Override
	public void mouseReleased(MouseEvent e) {
		int x = e.getX();
		int y = e.getY();
		ArrayList<GameObject> magnets = CurrentLevel.objectCollections.get("magnet");
		for(int i = 0; i < magnets.size(); i++) {
			Magnet mag = (Magnet)magnets.get(i);
			if (mag.clickedOn(x, y) && !CurrentLevel.activated.contains(i)) {
				mag.setImage("images/Magnet-2.png");
				CurrentLevel.activated.add(i);
			}
			else if (mag.clickedOn(x, y) && CurrentLevel.activated.contains(i)) {
				mag.setImage("images/Magnet-1.png");
				CurrentLevel.activated.remove(i);
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {}

	@Override
	public void mouseEntered(MouseEvent arg0) {}

	@Override
	public void mouseExited(MouseEvent arg0) {}

	@Override
	public void mousePressed(MouseEvent arg0) {}

	@Override
	public void mouseDragged(MouseEvent arg0) {}

	@Override
	public void mouseMoved(MouseEvent arg0) {}

}
